package cn.legym.garp.gateway.traffic.config;

import cn.legym.garp.gateway.traffic.dynamic.DynamicResourceManager;
import cn.legym.garp.gateway.traffic.dynamic.SentinelDatasourceWatcher;
import com.alibaba.cloud.sentinel.SentinelProperties;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;

/**
 * create by pipisun on 2021/9/10
 * copyright © 2017-2021 Legym Technology Co.,Ltd. All rights reserve
 * d.
 * file description:
 * 监听Sentinel规则数据源
 * last update by {} on {}
 * update description:
 */
@Component
@Aspect
@Slf4j
public class SentinelDataSourceAspect {

    @Autowired
    private ApplicationContext context;
    @Autowired
    private TrafficConfig trafficConfig;
    @Autowired
    private SentinelProperties sentinelProperties;
    @Autowired
    private SentinelDatasourceWatcher sentinelDatasourceWatcher;
    @Autowired
    private DynamicResourceManager dynamicResourceManager;

    /**
     * 等待数据源bean加载完成
     */
    @Pointcut("execution(public void com.alibaba.cloud.sentinel.custom.SentinelDataSourceHandler.afterSingletonsInstantiated(..))")
    public void cut() {
    }

    @Around("cut()")
    public Object around(ProceedingJoinPoint point) {
        try {
            Object result = point.proceed();
            if (trafficConfig.isEnabled()) {
                // 等待sentinelProperties中的datasource被BeanFactory加载完成
                sentinelDatasourceWatcher.onInit(context, sentinelProperties);
                sentinelDatasourceWatcher.addListener(dynamicResourceManager);
            }
            return result;
        } catch (Throwable e) {
            log.error("", e);
        }
        throw new IllegalStateException("initializing SentinelDatasourceWatcher failed");
    }
}
